﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Office.Tools.Ribbon;
using Microsoft.Office.Tools.Word;
using System.Collections;
using TestPlanWordWriter.Common;
using Microsoft.TeamFoundation.Client;
using Microsoft.TeamFoundation.WorkItemTracking.Client;
using Microsoft.TeamFoundation.TestManagement.Client;
using System.Windows.Forms;
using System.Xml.Linq;
using System.IO;
using TestPlanWordWriter.Common.Word;
using TestPlanWordWriter.UI.Properties;

namespace TestPlanWordWriter.UI
{
    public partial class TestPlanDocWriterRibbon
    {
        private const int FIRST_COLUMN_WIDTH_IN_CM = 2;

        private TfsTeamProjectCollection _teamProjectCollection = null;
        private string _teamProjectName = null;

        private void TestPlanDocWriterRibbon_Load(object sender, RibbonUIEventArgs e)
        {
        }

        private void FillTestPlanContentControl(List<UIControlInfo> controlsInfo)
        {
            if (controlsInfo.Count > 0)
            {
                TestInfoProgressForm progressForm = new TestInfoProgressForm();
                progressForm.Plans = controlsInfo;
                progressForm.TeamProjectCollection = _teamProjectCollection;
                progressForm.TeamProjectName = _teamProjectName;

                if (progressForm.ShowDialog() == DialogResult.OK)
                {
                    List<UIPlanInfo> testPlansInfo = progressForm.TestPlansInfo;

                    Microsoft.Office.Interop.Word.ContentControl templateControl = controlsInfo.Last().NativeControl;
                    string stylesXml = PrepareStylesXml(templateControl);
                    templateControl.Range.Delete();

                    foreach (UIPlanInfo item in testPlansInfo)
                    {
                        TestPlanInfo planInfo = item.PlanInfo;
                        Microsoft.Office.Interop.Word.ContentControl nativeControl = item.ControlInfo.NativeControl;
                        nativeControl.Range.Delete();

                        WordPlanContentBuilder sectionBuilder = new WordPlanContentBuilder(ThisAddIn.SettingsManager.DocWriterSettings, item.ControlInfo.ControlIdentification);
                        MemoryStream packageStream = new MemoryStream();
                        sectionBuilder.BuildPackageContent(planInfo, stylesXml, packageStream);
                        packageStream.Seek(0, SeekOrigin.Begin);

                        XDocument docToInsert = OpcToFlatConverter.OpcToFlat(packageStream);
                        string newControlContent = docToInsert.ToString();

                        nativeControl.Range.InsertXML(newControlContent);
                    }
                }
            }
        }

        private List<UIControlInfo> GetContentControlsToFill()
        {
            List<UIControlInfo> contentControlsToFill = new List<UIControlInfo>();

            Microsoft.Office.Interop.Word.Document currentDocument = Globals.ThisAddIn.Application.ActiveDocument;
            Document extendedDocument = Globals.Factory.GetVstoObject(currentDocument);
            if (extendedDocument.ContentControls.Count > 0)
            {
                foreach (Microsoft.Office.Interop.Word.ContentControl nativeControl in extendedDocument.ContentControls)
                {
                    if (nativeControl.Type == Microsoft.Office.Interop.Word.WdContentControlType.wdContentControlRichText)
                    {
                        string tag = nativeControl.Tag;
                        ContentControlIdentification controlIdentification = new ContentControlIdentification(tag);
                        if (controlIdentification.IsTestPlanControl)
                        {
                            UIControlInfo planControlInfo = new UIControlInfo();
                            planControlInfo.ControlIdentification = controlIdentification;
                            planControlInfo.NativeControl = nativeControl;
                            contentControlsToFill.Add(planControlInfo);
                        }
                    }
                }
            }

            //TODO: If more than one control we could show a form to allow unselect controls
            return contentControlsToFill;
        }

        private string PrepareStylesXml(Microsoft.Office.Interop.Word.ContentControl nativeControl)
        {
            try
            {
                Microsoft.Office.Interop.Word.Range currentRange = nativeControl.Range;
                currentRange.Delete();

                InsertParagraphStyleForPrepare(currentRange, ThisAddIn.SettingsManager.DocWriterSettings.TestPlanStyleName);
                InsertParagraphStyleForPrepare(currentRange, ThisAddIn.SettingsManager.DocWriterSettings.TestPlanDescriptionStyleName);

                foreach (TestSuiteSettings suiteSettings in ThisAddIn.SettingsManager.DocWriterSettings.TestSuiteLevelsSettings)
                {
                    InsertParagraphStyleForPrepare(currentRange, suiteSettings.TestSuiteStyleName);
                    InsertParagraphStyleForPrepare(currentRange, suiteSettings.TestSuiteDescription);
                }

                InsertParagraphStyleForPrepare(currentRange, ThisAddIn.SettingsManager.DocWriterSettings.TestCaseStyleName);
                InsertParagraphStyleForPrepare(currentRange, ThisAddIn.SettingsManager.DocWriterSettings.TestCaseDescriptionStyleName);

                InsertTableStyleForPrepare(currentRange, ThisAddIn.SettingsManager.DocWriterSettings.TestStepsTableStyleName);
                InsertTableStyleForPrepare(currentRange, ThisAddIn.SettingsManager.DocWriterSettings.TestResultsTableStyleName);

                string currentXml = nativeControl.Range.WordOpenXML;
                return currentXml;
            }
            catch(Exception ex)
            {
                string message = string.Format(
                    "There were problems preparing content styles, review styles in settings. Exception message: {0}",
                    ex.Message);
                MessageBox.Show(message);
                return null;
            }
        }

        private static void InsertTableStyleForPrepare(Microsoft.Office.Interop.Word.Range currentRange, string styleName)
        {
            if (!string.IsNullOrEmpty(styleName))
            {
                object testStepsTableStyleNameRef = styleName;
                currentRange.SetRange(currentRange.End, currentRange.End);
                Microsoft.Office.Interop.Word.Range tableTempRange = currentRange.Duplicate;
                currentRange.InsertParagraphAfter();
                Microsoft.Office.Interop.Word.Table tbl = currentRange.Tables.Add(tableTempRange, 1, 3);
                tbl.set_Style(ref testStepsTableStyleNameRef);
                currentRange.InsertParagraphAfter();
            }
        }

        private static void InsertParagraphStyleForPrepare(Microsoft.Office.Interop.Word.Range currentRange, string styleName)
        {
            if (!string.IsNullOrEmpty(styleName))
            {
                object planStyleNameRef = styleName;
                currentRange.set_Style(ref planStyleNameRef);
                currentRange.InsertAfter("content for style preparation");
                currentRange.InsertParagraphAfter();
            }
        }

        private void btnWriteInfo_Click(object sender, RibbonControlEventArgs e)
        {
            if (_teamProjectCollection == null)
            {
                MessageBox.Show("You have to select a valid TeamProject");
            }
            else
            {
                List<UIControlInfo> controlsToFill = GetContentControlsToFill();
                if (controlsToFill.Count > 0)
                {
                    FillTestPlanContentControl(controlsToFill);
                }
                else
                {
                    MessageBox.Show("There is no test plans controls in the document to refresh");
                }
            }
        }

        private void btnCreateControl_Click(object sender, RibbonControlEventArgs e)
        {
            if (_teamProjectCollection == null)
            {
                MessageBox.Show("You have to select a valid TeamProject");
            }
            else
            {
                CreateControlForm form = new CreateControlForm();
                form.TeamProjectCollection = _teamProjectCollection;
                form.TeamProjectName = _teamProjectName;
                DialogResult result = form.ShowDialog();
                if (result == DialogResult.OK)
                {
                    if (form.TestPlan != null)
                    {
                        Microsoft.Office.Interop.Word.ContentControl richTextBocControl =
                            Globals.ThisAddIn.Application.Selection.Range.ContentControls.Add(Microsoft.Office.Interop.Word.WdContentControlType.wdContentControlRichText);
                        richTextBocControl.Tag = ContentControlIdentification.BuildTag(form.TestPlan.Value);
                        string title = string.Format("TestPlan: {0} - {1}", form.TestPlan, form.TestPlanName);
                        if (title.Length > 64)
                        {
                            title = title.Substring(0, 64);
                        }
                        richTextBocControl.Title = title;
                    }
                    else
                    {
                        MessageBox.Show("Test Plan was not correctly selected");
                    }
                }
            }
        }

        private void btnCreateResultsControl_Click(object sender, RibbonControlEventArgs e)
        {
            if (_teamProjectCollection == null)
            {
                MessageBox.Show("You have to select a valid TeamProject");
            }
            else
            {
                CreateResultsControlForm form = new CreateResultsControlForm();
                form.TeamProjectCollection = _teamProjectCollection;
                form.TeamProjectName = _teamProjectName;
                DialogResult result = form.ShowDialog();
                if (result == DialogResult.OK)
                {
                    if (form.TestPlan != null)
                    {
                        Microsoft.Office.Interop.Word.ContentControl richTextBocControl =
                            Globals.ThisAddIn.Application.Selection.Range.ContentControls.Add(Microsoft.Office.Interop.Word.WdContentControlType.wdContentControlRichText);
                        richTextBocControl.Tag = ContentControlIdentification.BuildTag(form.TestPlan.Value, form.ResultsSettings);
                        string title;
                        if (form.ResultsSettings.Options == TestResultsOptions.Build)
                        {
                            title = string.Format("Build: {2}. TestPlan: {0} - {1}", form.TestPlan, form.TestPlanName, form.ResultsSettings.SpecificBuildNumber);
                        }
                        else
                        {
                            title = string.Format("Options: {2}. TestPlan: {0} - {1}", form.TestPlan, form.TestPlanName, form.ResultsSettings.Options.ToString());
                        }
                        if (title.Length > 64)
                        {
                            title = title.Substring(0, 64);
                        }
                        richTextBocControl.Title = title;
                    }
                    else
                    {
                        MessageBox.Show("Test Plan was not correctly selected");
                    }
                }
            }
        }

        private void btnSettings_Click(object sender, RibbonControlEventArgs e)
        {
            SettingsForm form = new SettingsForm();
            form.Settings = ThisAddIn.SettingsManager.DocWriterSettings;

            DialogResult result = form.ShowDialog();
            if (result == DialogResult.OK)
            {
            }
        }

        private void btnSelectTeam_Click(object sender, RibbonControlEventArgs e)
        {
            try
            {
                TeamProjectPicker tpp = new TeamProjectPicker(TeamProjectPickerMode.SingleProject, false);
                DialogResult result = tpp.ShowDialog();
                if (result == DialogResult.OK)
                {
                    _teamProjectName = tpp.SelectedProjects[0].Name;
                    _teamProjectCollection = tpp.SelectedTeamProjectCollection;

                    btnCreateControl.Enabled = true;
                    btnCreateResultsControl.Enabled = true;
                    btnWriteInfo.Enabled = true;
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        private void btnExportSettings_Click(object sender, RibbonControlEventArgs e)
        {
            if (exportSettingsDialog.ShowDialog() == DialogResult.OK)
            {
                string fileName = exportSettingsDialog.FileName;
                ThisAddIn.SettingsManager.Export(fileName);
            }
        }

        private void btnImportSettings_Click(object sender, RibbonControlEventArgs e)
        {
            if (importSettingsDialog.ShowDialog() == DialogResult.OK)
            {
                string fileName = importSettingsDialog.FileName;
                ThisAddIn.SettingsManager.Import(fileName);
            }
        }
    }
}
